//package org.jsoncrypto;
//
//import java.math.BigInteger;
//import java.security.KeyPair;
//import java.security.KeyPairGenerator;
//import java.security.NoSuchAlgorithmException;
//import java.security.SecureRandom;
//import java.security.spec.ECGenParameterSpec;
//
//import junit.framework.TestCase;
//
//import org.bouncycastle.asn1.ASN1ObjectIdentifier;
//import org.bouncycastle.asn1.sec.SECNamedCurves;
//import org.bouncycastle.asn1.x9.X9ECParameters;
//import org.bouncycastle.crypto.params.ECDomainParameters;
//import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
//import org.bouncycastle.crypto.params.ECPublicKeyParameters;
//import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
//import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
//import org.bouncycastle.jcajce.provider.asymmetric.ec.ECUtil;
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
//import org.bouncycastle.math.ec.ECCurve;
//import org.bouncycastle.math.ec.ECPoint;
//import org.bouncycastle.util.encoders.Hex;
//import org.json.JSONException;
//import org.json.JSONObject;
//import org.jsoncrypto.util.Base64;
//import org.junit.Test;
//
//public class JweECDH_EStest extends TestCase {
//  final String joeStr = "{\"iss\":\"joe\",\r\n" + " \"exp\":1300819380,\r\n" + " \"http://example.com/is_root\":true}";
//
//  static final byte[] ec128_1_x = { 48, (byte) 160, 66, 76, (byte) 210, 28, 41, 68, (byte) 131, (byte) 138, 45, 117,
//      (byte) 201, 43, 55, (byte) 231, 110, (byte) 162, 13, (byte) 159, 0, (byte) 137, 58, 59, 78, (byte) 238,
//      (byte) 138, 60, 10, (byte) 175, (byte) 236, 62 };
//  static final byte[] ec128_1_y = { (byte) 224, 75, 101, (byte) 233, 36, 86, (byte) 217, (byte) 136, (byte) 139, 82,
//      (byte) 179, 121, (byte) 189, (byte) 251, (byte) 213, 30, (byte) 232, 105, (byte) 239, 31, 15, (byte) 198, 91,
//      102, 89, 105, 91, 108, (byte) 206, 8, 23, 35 };
//  static final byte[] ec128_1_d = { (byte) 243, (byte) 189, 12, 7, (byte) 168, 31, (byte) 185, 50, 120, 30, (byte) 213,
//      39, 82, (byte) 246, 12, (byte) 200, (byte) 154, 107, (byte) 229, (byte) 229, 25, 52, (byte) 254, 1, (byte) 147,
//      (byte) 141, (byte) 219, 85, (byte) 216, (byte) 247, 120, 1 };
//
//  static final String ec128_a_priv = "072f2322c0e75e0c851764b42181996778fd22592f87e5d43836097429a1c3fc";
//  // static final String ec128_a_pub =
//  // "04ed3c831bf3e1059f12077f4be4fdfe905573d1c67645b47d4864ea179dde9986a9a6ad34274a80fc94b3a5ef6c6e782c227a3963a6a42650976da6ade990a161";
//  static final String ec128_b_priv = "1a3eda89dc067871530601f934c6428574f837507c578e45bd10a29b2e019bfb";
//  // static final String ec128_b_pub =
//  // "049d887ec41f36201c1868f1c09c9a93cb9d5a0ff9d08af8dde2175b25ffaa834a6caadaba025a4477beb53af076bdab597153666c70d8458c49df24713ee55e85";
//
//  BigInteger ec128_a_D;
//  BigInteger ec128_a_X;
//  BigInteger ec128_a_Y;
//  String ec128_a_header;
//  BigInteger ec128_b_D;
//  BigInteger ec128_b_X;
//  BigInteger ec128_b_Y;
//  String ec128_b_header;
//
//  ECPublicKeyParameters mEcPublicKeyParametersA;
//  ECPrivateKeyParameters mEcPrivateKeyParametersA;
//  ECPublicKeyParameters mEcPublicKeyParametersB;
//  ECPrivateKeyParameters mEcPrivateKeyParametersB;
//
//  public void setUp() throws Exception {
//    
//    ASN1ObjectIdentifier oid = SECNamedCurves.getOID("secp128r1");
//    X9ECParameters x9ECParameters = ECUtil.getNamedCurveByOid(oid);
//    // ECCurve curve = x9ECParameters.getCurve();
//
//    {
//      byte[] ec128_a_priv_bytes = Hex.decode(ec128_a_priv);
//      ec128_a_D = new BigInteger(1, ec128_a_priv_bytes);
//      ECPoint pubA = x9ECParameters.getG().multiply(ec128_a_D);
//      ec128_a_X = pubA.getX().toBigInteger();
//      ec128_a_Y = pubA.getY().toBigInteger();
//      // byte[] xyBytes = Hex.decode(ec128_a_pub);
//      // byte[] xBytes = new byte[xyBytes.length/2];
//      // System.arraycopy(xyBytes, 0, xBytes, 0, xBytes.length);
//      // ec128_a_X = new BigInteger(1, xBytes);
//      // String ec128_a_X_b64 = Base64.encodeBytes(xBytes,
//      // org.xmldap.util.Base64.DONT_BREAK_LINES |
//      // org.xmldap.util.Base64.URL);
//      String ec128_a_X_b64 = Base64.encodeBytes(ec128_a_X.toByteArray(), org.jsoncrypto.util.Base64.DONT_BREAK_LINES
//          | org.jsoncrypto.util.Base64.URL);
//      // byte[] yBytes = new byte[xyBytes.length/2];
//      // System.arraycopy(xyBytes, xBytes.length/2, yBytes, 0,
//      // yBytes.length);
//      // ec128_a_Y = new BigInteger(1, yBytes);
//      // String ec128_a_Y_b64 = Base64.encodeBytes(yBytes,
//      // org.xmldap.util.Base64.DONT_BREAK_LINES |
//      // org.xmldap.util.Base64.URL);
//      String ec128_a_Y_b64 = Base64.encodeBytes(ec128_a_Y.toByteArray(), org.jsoncrypto.util.Base64.DONT_BREAK_LINES
//          | org.jsoncrypto.util.Base64.URL);
//      ec128_a_header = "{\"epk\": {\"int\":\"HS256\", \"jwk\": [{\r\n" + " \"crv\":\"secp128r1\",\r\n" + " \"x\":\""
//          + ec128_a_X_b64 + "\",\r\n" + " \"y\":\"" + ec128_a_Y_b64 + "\"}]}}";
//
//      ECDomainParameters ecDomainParameters = new ECDomainParameters(x9ECParameters.getCurve(), x9ECParameters.getG(),
//          x9ECParameters.getN(), x9ECParameters.getH(), x9ECParameters.getSeed());
//
//      mEcPublicKeyParametersA = new ECPublicKeyParameters(pubA, ecDomainParameters);
//      mEcPrivateKeyParametersA = new ECPrivateKeyParameters(ec128_a_D, ecDomainParameters);
//
//    }
//    {
//      byte[] ec128_b_priv_bytes = Hex.decode(ec128_b_priv);
//      ec128_b_D = new BigInteger(1, ec128_b_priv_bytes);
//      ECPoint pubB = x9ECParameters.getG().multiply(ec128_b_D);
//      ec128_b_X = pubB.getX().toBigInteger();
//      ec128_b_Y = pubB.getY().toBigInteger();
//      // byte[] xyBytes = Hex.decode(ec128_b_pub);
//      // byte[] xBytes = new byte[xyBytes.length/2];
//      // System.arraycopy(xyBytes, 0, xBytes, 0, xBytes.length);
//      // ec128_b_X = new BigInteger(1, xBytes);
//      String ec128_b_X_b64 = Base64.encodeBytes(ec128_b_X.toByteArray(), org.jsoncrypto.util.Base64.DONT_BREAK_LINES
//          | org.jsoncrypto.util.Base64.URL);
//      // String ec128_b_X_b64 = Base64.encodeBytes(xBytes,
//      // org.xmldap.util.Base64.DONT_BREAK_LINES |
//      // org.xmldap.util.Base64.URL);
//      // byte[] yBytes = new byte[xyBytes.length/2];
//      // System.arraycopy(xyBytes, xBytes.length/2, yBytes, 0,
//      // yBytes.length);
//      // ec128_b_Y = new BigInteger(1, yBytes);
//      // String ec128_b_Y_b64 = Base64.encodeBytes(yBytes,
//      // org.xmldap.util.Base64.DONT_BREAK_LINES |
//      // org.xmldap.util.Base64.URL);
//      String ec128_b_Y_b64 = Base64.encodeBytes(ec128_b_Y.toByteArray(), org.jsoncrypto.util.Base64.DONT_BREAK_LINES
//          | org.jsoncrypto.util.Base64.URL);
//      ec128_b_header = "{\"int\":\"HS256\", \"epk\": {\"jwk\": [{\r\n" + " \"crv\":\"secp128r1\",\r\n" + " \"x\":\""
//          + ec128_b_X_b64 + "\",\r\n" + " \"y\":\"" + ec128_b_Y_b64 + "\"}]}}";
//      
//      ECDomainParameters ecDomainParameters = new ECDomainParameters(x9ECParameters.getCurve(), x9ECParameters.getG(),
//          x9ECParameters.getN(), x9ECParameters.getH(), x9ECParameters.getSeed());
//
//      mEcPublicKeyParametersB = new ECPublicKeyParameters(pubB, ecDomainParameters);
//      mEcPrivateKeyParametersB = new ECPrivateKeyParameters(ec128_b_D, ecDomainParameters);
//
//    }
//    
//  }
//
//  private void testEc(
//      byte[] contentBytes,
//      String headerStr,
//      ECPublicKeyParameters ecPublicKeyParametersA,
//      ECPrivateKeyParameters ecPrivateKeyParametersA,
//      ECPrivateKeyParameters ecPrivateKeyParametersB) throws JSONException, JcBaseException 
//  {
//    String jwtHeaderSegment = headerStr;
//    JSONObject header = new JSONObject(jwtHeaderSegment);
//    JcEnc_A128CBCHS256 enc = new JcEnc_A128CBCHS256(header);
//    JweECDH_ES senderJwe = new JweECDH_ES(enc);
//    String encrypted = senderJwe.encrypt(contentBytes, ecPrivateKeyParametersB, ecPublicKeyParametersA);
//    String[] split = encrypted.split("\\.");
//    assertEquals(5, split.length);
//    
//    JweECDH_ES receiverJwe = new JweECDH_ES(encrypted);
//    byte[] bytes = receiverJwe.decrypt(ecPrivateKeyParametersA);
//    assertEquals(new String(contentBytes), new String(bytes));
//  }
//  
//  @Test
//  public void test() throws JcBaseException, JSONException {
//    testEc(joeStr.getBytes(), ec128_b_header, mEcPublicKeyParametersA, mEcPrivateKeyParametersA, mEcPrivateKeyParametersB);
//  }
//
//  public void testRubbishAlg() throws JcBaseException, JSONException {
//    String jwtHeaderSegment = ec128_b_header;
//    JSONObject header = new JSONObject(jwtHeaderSegment);
//    header.put("alg", "rubbish");
//    JcEnc_A128CBCHS256 enc = new JcEnc_A128CBCHS256(header);
//    try {
//      new JweECDH_ES(enc);
//      fail();
//    } catch (JcBaseException e) {}
//  }
//
//  public void testOptionalAlg() throws JcBaseException, JSONException {
//    String jwtHeaderSegment = ec128_b_header;
//    JSONObject header = new JSONObject(jwtHeaderSegment);
//    // remove alg
//    header.put("alg", (Object)null); 
//    JcEnc_A128CBCHS256 enc = new JcEnc_A128CBCHS256(header);
//    // should set the alg
//    new JweECDH_ES(enc);
//  }
//
//  public void testECencryptionEphemeralKey() throws Exception {
//    String curveName = "secp256r1";
//
//    ECDomainParameters ecDomainParameters;
//    {
//      ASN1ObjectIdentifier oid = JcBase.getNamedCurveOid(curveName);
//      if (oid == null) {
//        throw new NoSuchAlgorithmException("JWT EC curve: " + curveName);
//      }
//
//      X9ECParameters x9ECParameters = SECNamedCurves.getByOID(oid);
//      ECCurve curve = x9ECParameters.getCurve();
//      ecDomainParameters = new ECDomainParameters(curve, x9ECParameters.getG(), x9ECParameters.getN(),
//          x9ECParameters.getH(), x9ECParameters.getSeed());
//
//    }
//
//    ECGenParameterSpec ecGenSpec = new ECGenParameterSpec(curveName);
//
//    KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", new BouncyCastleProvider());
//
//    g.initialize(ecGenSpec, new SecureRandom());
//
//    // java.lang.ClassCastException:
//    // org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey cannot
//    // be
//    // cast to org.bouncycastle.asn1.sec.ECPrivateKey
//
//    KeyPair pair = g.generateKeyPair();
//    BCECPublicKey publicKey = (BCECPublicKey) pair.getPublic();
//    BCECPrivateKey privateKey = (BCECPrivateKey) pair.getPrivate();
//
//    // Bouncycastle
//    BigInteger X = publicKey.getQ().getX().toBigInteger();
//    BigInteger Y = publicKey.getQ().getY().toBigInteger();
//    BigInteger D = privateKey.getD();
//
//    // JCE
//    // BigInteger X = publicKey.getQ().getAffineX();
//    // BigInteger Y = publicKey.getQ().getAffineY();
//    // BigInteger D = privateKey.getS();
//    String X_b64 = Base64.encodeBytes(X.toByteArray(), org.jsoncrypto.util.Base64.DONT_BREAK_LINES
//        | org.jsoncrypto.util.Base64.URL);
//    String Y_b64 = Base64.encodeBytes(Y.toByteArray(), org.jsoncrypto.util.Base64.DONT_BREAK_LINES
//        | org.jsoncrypto.util.Base64.URL);
//    String D_b64 = Base64.encodeBytes(D.toByteArray(), org.jsoncrypto.util.Base64.DONT_BREAK_LINES
//        | org.jsoncrypto.util.Base64.URL);
//    System.out.println("ECDH-ES D base64=" + D_b64);
//
//    String header = "{\"alg\":\"ECDH-ES\",\r\n" + "\"enc\":\"" + JcBase.ENC_ALG_A256GCM + "\",\r\n"
//        + "\"iv\":\"__79_Pv6-fg\",\r\n" + "\"epk\": {\"jwk\": [{\r\n" + " \"crv\":\"" + curveName + "\",\r\n"
//        + " \"x\":\"" + X_b64 + "\",\r\n" + " \"y\":\"" + Y_b64 + "\"}]}}";
//
//    ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(D, ecDomainParameters);
//    
//    testEc(joeStr.getBytes(), header, mEcPublicKeyParametersB, ecPrivateKeyParameters, mEcPrivateKeyParametersB);
//
////    String encrypted = JcBase.encrypt(joeStr.getBytes(), jwtHeaderSegment, mEcPublicKeyParametersB, ecPrivateKeyParameters);
////
////    String[] split = encrypted.split("\\.");
////
////    assertEquals(4, split.length);
////
////    String newJwtHeaderSegment = new String(Base64.decodeUrl(split[0]));
////    JSONObject newJwtHeader = new JSONObject(newJwtHeaderSegment);
////    JSONObject oldJwtHeader = new JSONObject(jwtHeaderSegment);
////
////    assertEquals(oldJwtHeader.get("alg"), newJwtHeader.get("alg"));
////    assertEquals(oldJwtHeader.get("enc"), newJwtHeader.get("enc"));
////    String ivB64 = oldJwtHeader.optString("iv", null);
////    if (ivB64 != null) {
////      assertEquals(ivB64, newJwtHeader.get("iv"));
////    }
////    System.out.println("ECDH-ES jwtHeaderSegment: " + jwtHeaderSegment);
////    System.out.println("ECDH-ES jwtHeaderSegment base64: " + split[0]);
////    System.out.println("ECDH-ES jwtSymmetricKeySegment base64: " + split[1]);
////    System.out.println("ECDH-ES jwtCryptoSegment base64: " + split[2]);
////
////    byte[] cleartext = JcBase.decrypt(encrypted, mEcPrivateKeyParametersB);
////    assertTrue(Arrays.equals(joeStr.getBytes(), cleartext));
//  }
//
//}
